home *** CD-ROM | disk | FTP | other *** search
/ GFX Sensations 1 / Graphic Sensations - Volume 1.iso / tools / amiga / 3d_tools / shelly15.lha / shelly / shelly.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-06-06  |  56.1 KB  |  2,430 lines

  1. /*****************************************************/
  2. /* ShellyV1.5: The ShellShapeGenerator by:           */
  3. /*         RANDi                                     */
  4. /*              (rschultz@informatik.uni-rostock.de) */
  5. /*****************************************************/
  6.  
  7. #include <math.h>
  8. #include <stdlib.h>
  9. #include <stdio.h>
  10. #include <string.h>
  11. #include <memory.h>
  12.  
  13. #include "shelly.h"
  14.  
  15. int countw = 0, counth = 0, countp = 0, countl = 0, countt = 0;
  16. double camx = 0, camy = 500, camz = 500;
  17. int camposspecified = NO;
  18. struct lmerk *bigllist;
  19. struct tmerk *bigtlist;
  20.  
  21. /********************************************/
  22. /*cot:                                      */
  23. /********************************************/
  24. double
  25. cot (double in)
  26. {
  27.   if (sin (in) == 0)
  28.     return (0);
  29.   else
  30.     return (cos (in) / sin (in));
  31. }
  32.  
  33.  
  34. /********************************************/
  35. /*round:                                    */
  36. /********************************************/
  37. double
  38. round (double in)
  39. {
  40.   if (in - floor (in) < 0.5)
  41.     return (floor (in));
  42.   else
  43.     return (floor (in) + 1);
  44. }
  45.  
  46.  
  47. /********************************************/
  48. /*myfree:                                   */
  49. /********************************************/
  50. int
  51. myfree (struct punkt *anker1)
  52. {
  53.   struct punkt *hp, *hpnew;
  54.   if (anker1 == NULL)
  55.     return (0);
  56.  
  57.   hp = anker1;
  58.   hpnew = hp;
  59.   do
  60.     {
  61.       hp = hpnew;
  62.       hpnew = (*hp).next;
  63.  
  64.       free (hp);
  65.     }
  66.   while (hpnew != NULL);
  67.  
  68.   return (0);
  69. }
  70.  
  71.  
  72. /********************************************/
  73. /*mycopystr:                                */
  74. /********************************************/
  75. char *
  76. mycopystr (char *source, char *destination, char endchar)
  77. {
  78.   int ende = 1;
  79.   char *merk;
  80.  
  81.   merk = destination;        /* merk points now on destination */
  82.   while (ende)
  83.     {
  84.       if ((*source == '\0') || (*source == endchar))
  85.     {
  86.       ende = 0;
  87.     }
  88.       else
  89.     {
  90.       *destination = *source;
  91.       destination++;
  92.       source++;
  93.     }            /* if */
  94.     }                /* while */
  95.   *destination = '\0';
  96.   return (merk);
  97. }
  98.  
  99.  
  100. /********************************************/
  101. /*filecopy:                                 */
  102. /********************************************/
  103. void
  104. filecopy (FILE * source, FILE * dest)
  105. {
  106.   int a, b;
  107.  
  108.   fseek (source, 0, 0);
  109.   do
  110.     {
  111.       a = fgetc (source);
  112.       if (a != EOF)
  113.     {
  114.       b = fputc (a, dest);
  115.       if (b == EOF)
  116.         {
  117.           fclose (source);
  118.           fclose (dest);
  119.           exit (5);
  120.         };            /* if */
  121.     };            /* if */
  122.     }
  123.   while (a != EOF);
  124. }
  125.  
  126. /********************************************/
  127. /*ReadInfile:                               */
  128. /********************************************/
  129. void
  130. ReadInfile (struct ShellyArguments *ShellyArgs, char *fin)
  131. {
  132.   char readline[laenge], hilf[laenge], *hp;
  133.   FILE *fp;
  134.  
  135.   /* set some defaults */
  136.  
  137.   (*ShellyArgs).output = POV;
  138.   (*ShellyArgs).mode = NORMAL;
  139.   (*ShellyArgs).Scano = 0.05;
  140.   (*ShellyArgs).Scans = 0.05;
  141.   (*ShellyArgs).heightdiffo = 0.1;
  142.   (*ShellyArgs).heightdiffs = 0.1;
  143.  
  144.   (*ShellyArgs).Scale = 1.0;
  145.   (*ShellyArgs).Render = NO;
  146.   (*ShellyArgs).N2 = 0;
  147.   (*ShellyArgs).N3 = 0;
  148.   (*ShellyArgs).N = 0;
  149.  
  150.  
  151.   mycopystr ("-f +d +w200 +h160", (*ShellyArgs).povargs, '\0');
  152.  
  153.  
  154.   fp = fopen (fin, "r");
  155.   if (fp != NULL)
  156.     {
  157.       fprintf (stdout, "Parsing:");
  158.       while (fgets (readline, laenge, fp) != NULL)
  159.     {
  160.       fprintf (stdout, ".");
  161.  
  162.       hp = strstr (readline, "alpha:");
  163.       if (hp != NULL)
  164.         {
  165.           mycopystr (hp + 6, hilf, '\0');
  166.           (*ShellyArgs).alpha = atof (hilf);
  167.         }            /* if */
  168.       hp = strstr (readline, "beta:");
  169.       if (hp != NULL)
  170.         {
  171.           mycopystr (hp + 5, hilf, '\0');
  172.           (*ShellyArgs).beta = atof (hilf);
  173.         }            /* if */
  174.       hp = strstr (readline, "phi:");
  175.       if (hp != NULL)
  176.         {
  177.           mycopystr (hp + 4, hilf, '\0');
  178.           (*ShellyArgs).phi = atof (hilf);
  179.         }            /* if */
  180.       hp = strstr (readline, "my:");
  181.       if (hp != NULL)
  182.         {
  183.           mycopystr (hp + 3, hilf, '\0');
  184.           (*ShellyArgs).my = atof (hilf);
  185.         }            /* if */
  186.       hp = strstr (readline, "omega:");
  187.       if (hp != NULL)
  188.         {
  189.           mycopystr (hp + 6, hilf, '\0');
  190.           (*ShellyArgs).omega = atof (hilf);
  191.         }            /* if */
  192.       hp = strstr (readline, "smin:");
  193.       if (hp != NULL)
  194.         {
  195.           mycopystr (hp + 5, hilf, '\0');
  196.           (*ShellyArgs).smin = atof (hilf);
  197.         }            /* if */
  198.       hp = strstr (readline, "smax:");
  199.       if (hp != NULL)
  200.         {
  201.           mycopystr (hp + 5, hilf, '\0');
  202.           (*ShellyArgs).smax = atof (hilf);
  203.         }            /* if */
  204.       hp = strstr (readline, "sd:");
  205.       if (hp != NULL)
  206.         {
  207.           mycopystr (hp + 3, hilf, '\0');
  208.           (*ShellyArgs).sd = atof (hilf);
  209.         }            /* if */
  210.       hp = strstr (readline, "A:");
  211.       if (hp != NULL)
  212.         {
  213.           mycopystr (hp + 2, hilf, '\0');
  214.           (*ShellyArgs).A = atof (hilf);
  215.         }            /* if */
  216.       hp = strstr (readline, "a:");
  217.       if (hp != NULL)
  218.         {
  219.           mycopystr (hp + 2, hilf, '\0');
  220.           (*ShellyArgs).a = atof (hilf);
  221.         }            /* if */
  222.       hp = strstr (readline, "b:");
  223.       if (hp != NULL)
  224.         {
  225.           mycopystr (hp + 2, hilf, '\0');
  226.           (*ShellyArgs).b = atof (hilf);
  227.         }            /* if */
  228.       hp = strstr (readline, "P:");
  229.       if (hp != NULL)
  230.         {
  231.           mycopystr (hp + 2, hilf, '\0');
  232.           (*ShellyArgs).P = atof (hilf);
  233.         }            /* if */
  234.       hp = strstr (readline, "W1:");
  235.       if (hp != NULL)
  236.         {
  237.           mycopystr (hp + 3, hilf, '\0');
  238.           (*ShellyArgs).W1 = atof (hilf);
  239.         }            /* if */
  240.       hp = strstr (readline, "W2:");
  241.       if (hp != NULL)
  242.         {
  243.           mycopystr (hp + 3, hilf, '\0');
  244.           (*ShellyArgs).W2 = atof (hilf);
  245.         }            /* if */
  246.       hp = strstr (readline, "N:");
  247.       if (hp != NULL)
  248.         {
  249.           mycopystr (hp + 2, hilf, '\0');
  250.           (*ShellyArgs).N = atof (hilf);
  251.         }            /* if */
  252.       hp = strstr (readline, "L:");
  253.       if (hp != NULL)
  254.         {
  255.           mycopystr (hp + 2, hilf, '\0');
  256.           (*ShellyArgs).L = atof (hilf);
  257.         }            /* if */
  258.       hp = strstr (readline, "omin:");
  259.       if (hp != NULL)
  260.         {
  261.           mycopystr (hp + 5, hilf, '\0');
  262.           (*ShellyArgs).omin = atof (hilf);
  263.         }            /* if */
  264.       hp = strstr (readline, "omax:");
  265.       if (hp != NULL)
  266.         {
  267.           mycopystr (hp + 5, hilf, '\0');
  268.           (*ShellyArgs).omax = atof (hilf);
  269.         }            /* if */
  270.       hp = strstr (readline, "od:");
  271.       if (hp != NULL)
  272.         {
  273.           mycopystr (hp + 3, hilf, '\0');
  274.           (*ShellyArgs).od = atof (hilf);
  275.         }            /* if */
  276.       hp = strstr (readline, "Hdo:");
  277.       if (hp != NULL)
  278.         {
  279.           mycopystr (hp + 4, hilf, '\0');
  280.           (*ShellyArgs).heightdiffo = atof (hilf);
  281.         }            /* if */
  282.       hp = strstr (readline, "Hds:");
  283.       if (hp != NULL)
  284.         {
  285.           mycopystr (hp + 4, hilf, '\0');
  286.           (*ShellyArgs).heightdiffs = atof (hilf);
  287.         }            /* if */
  288.       hp = strstr (readline, "Scans:");
  289.       if (hp != NULL)
  290.         {
  291.           mycopystr (hp + 6, hilf, '\0');
  292.           (*ShellyArgs).Scans = atof (hilf);
  293.         }            /* if */
  294.       hp = strstr (readline, "Scano:");
  295.       if (hp != NULL)
  296.         {
  297.           mycopystr (hp + 6, hilf, '\0');
  298.           (*ShellyArgs).Scano = atof (hilf);
  299.         }            /* if */
  300.  
  301.       hp = strstr (readline, "Scale:");
  302.       if (hp != NULL)
  303.         {
  304.           mycopystr (hp + 6, hilf, '\0');
  305.           (*ShellyArgs).Scale = atof (hilf);
  306.         }            /* if */
  307.  
  308.       hp = strstr (readline, "POV");
  309.       if (hp != NULL)
  310.         {
  311.           (*ShellyArgs).output = POV;
  312.         }            /* if */
  313.       hp = strstr (readline, "RPL");
  314.       if (hp != NULL)
  315.         {
  316.           (*ShellyArgs).output = RPL;
  317.         }            /* if */
  318.       hp = strstr (readline, "T3D");
  319.       if (hp != NULL)
  320.         {
  321.           (*ShellyArgs).output = T3D;
  322.         }            /* if */
  323.       hp = strstr (readline, "RAW");
  324.       if (hp != NULL)
  325.         {
  326.           (*ShellyArgs).output = RAW;
  327.         }            /* if */
  328.       hp = strstr (readline, "X3D");
  329.       if (hp != NULL)
  330.         {
  331.           (*ShellyArgs).output = X3D;
  332.         }            /* if */
  333.  
  334.       hp = strstr (readline, "NORMAL");
  335.       if (hp != NULL)
  336.         {
  337.           (*ShellyArgs).mode = NORMAL;
  338.         }            /* if */
  339.       hp = strstr (readline, "NODULE");
  340.       if (hp != NULL)
  341.         {
  342.           (*ShellyArgs).mode = NODULE;
  343.         }            /* if */
  344.       hp = strstr (readline, "NEWNOD");
  345.       if (hp != NULL)
  346.         {
  347.           (*ShellyArgs).mode = NEWNOD;
  348.         }            /* if */
  349.       hp = strstr (readline, "RENDER");
  350.       if (hp != NULL)
  351.         {
  352.           (*ShellyArgs).Render = YES;
  353.         }            /* if */
  354.  
  355.       hp = strstr (readline, "POVARGS:");
  356.       if (hp != NULL)
  357.         mycopystr (hp + 8, (*ShellyArgs).povargs, '\n');
  358.  
  359.       hp = strstr (readline, "P2:");
  360.       if (hp != NULL)
  361.         {
  362.           mycopystr (hp + 3, hilf, '\0');
  363.           (*ShellyArgs).P2 = atof (hilf);
  364.         }            /* if */
  365.       hp = strstr (readline, "W12:");
  366.       if (hp != NULL)
  367.         {
  368.           mycopystr (hp + 4, hilf, '\0');
  369.           (*ShellyArgs).W12 = atof (hilf);
  370.         }            /* if */
  371.       hp = strstr (readline, "W22:");
  372.       if (hp != NULL)
  373.         {
  374.           mycopystr (hp + 4, hilf, '\0');
  375.           (*ShellyArgs).W22 = atof (hilf);
  376.         }            /* if */
  377.       hp = strstr (readline, "N2:");
  378.       if (hp != NULL)
  379.         {
  380.           mycopystr (hp + 3, hilf, '\0');
  381.           (*ShellyArgs).N2 = atof (hilf);
  382.         }            /* if */
  383.       hp = strstr (readline, "L2:");
  384.       if (hp != NULL)
  385.         {
  386.           mycopystr (hp + 3, hilf, '\0');
  387.           (*ShellyArgs).L2 = atof (hilf);
  388.         }            /* if */
  389.       hp = strstr (readline, "P3:");
  390.       if (hp != NULL)
  391.         {
  392.           mycopystr (hp + 3, hilf, '\0');
  393.           (*ShellyArgs).P3 = atof (hilf);
  394.         }            /* if */
  395.       hp = strstr (readline, "W13:");
  396.       if (hp != NULL)
  397.         {
  398.           mycopystr (hp + 4, hilf, '\0');
  399.           (*ShellyArgs).W13 = atof (hilf);
  400.         }            /* if */
  401.       hp = strstr (readline, "W23:");
  402.       if (hp != NULL)
  403.         {
  404.           mycopystr (hp + 4, hilf, '\0');
  405.           (*ShellyArgs).W23 = atof (hilf);
  406.         }            /* if */
  407.       hp = strstr (readline, "N3:");
  408.       if (hp != NULL)
  409.         {
  410.           mycopystr (hp + 3, hilf, '\0');
  411.           (*ShellyArgs).N3 = atof (hilf);
  412.         }            /* if */
  413.       hp = strstr (readline, "L3:");
  414.       if (hp != NULL)
  415.         {
  416.           mycopystr (hp + 3, hilf, '\0');
  417.           (*ShellyArgs).L3 = atof (hilf);
  418.         }            /* if */
  419.       hp = strstr (readline, "Off2:");
  420.       if (hp != NULL)
  421.         {
  422.           mycopystr (hp + 5, hilf, '\0');
  423.           (*ShellyArgs).Off2 = atof (hilf);
  424.         }            /* if */
  425.       hp = strstr (readline, "Off3:");
  426.       if (hp != NULL)
  427.         {
  428.           mycopystr (hp + 5, hilf, '\0');
  429.           (*ShellyArgs).Off3 = atof (hilf);
  430.         }            /* if */
  431.       hp = strstr (readline, "camx:");
  432.       if (hp != NULL)
  433.         {
  434.           mycopystr (hp + 5, hilf, '\0');
  435.           camx = atof (hilf);
  436.           camposspecified = YES;
  437.         }            /* if */
  438.       hp = strstr (readline, "camy:");
  439.       if (hp != NULL)
  440.         {
  441.           mycopystr (hp + 5, hilf, '\0');
  442.           camy = atof (hilf);
  443.           camposspecified = YES;
  444.         }            /* if */
  445.       hp = strstr (readline, "camz:");
  446.       if (hp != NULL)
  447.         {
  448.           mycopystr (hp + 5, hilf, '\0');
  449.           camz = atof (hilf);
  450.           camposspecified = YES;
  451.         }            /* if */
  452.  
  453.     }            /* while */
  454.  
  455.       fprintf (stdout, "\n");
  456.       if (fclose (fp) != 0)
  457.     fprintf (stdout, "Error while closing file: %s!\n", fin);
  458.     }
  459.   else
  460.     {
  461.       fprintf (stdout, "Could not open datafile: %s!\n", fin);
  462.       exit (5);
  463.     }
  464. }                /* ReadInfile */
  465.  
  466.  
  467. /********************************************/
  468. /* triangulate:                             */
  469. /*                                          */
  470. /********************************************/
  471. int
  472. triangulate (struct punkt *list1, struct punkt *list2, struct triangle **result)
  473. {
  474.   struct punkt *p11, *p12, *p21, *p22;
  475.   struct triangle *tp, *tp2, *anker = NULL;
  476.   int ende = 1;
  477.  
  478.   if ((list1 == NULL) || (list2 == NULL))
  479.     return (5);
  480.  
  481.   p11 = list1;
  482.   p21 = list2;
  483.  
  484.   while (ende)
  485.     {
  486.       p12 = p11->next;
  487.       p22 = p21->next;
  488.  
  489.  
  490.       if ((p11->next == NULL) && (p21->next == NULL))
  491.     ende = 0;
  492.       else if (p11->next == NULL)
  493.     {
  494.       tp = calloc (1, sizeof (struct triangle));
  495.       if (tp != NULL)
  496.         {
  497.           tp->p1 = p21;
  498.           tp->p2 = p22;
  499.           tp->p3 = p11;
  500.           if (anker == NULL)
  501.         anker = tp;
  502.           else
  503.         tp2->next = tp;
  504.           tp2 = tp;
  505.         }
  506.       p21 = p22;
  507.     }
  508.       else if (p21->next == NULL)
  509.     {
  510.       tp = calloc (1, sizeof (struct triangle));
  511.       if (tp != NULL)
  512.         {
  513.           tp->p1 = p11;
  514.           tp->p2 = p21;
  515.           tp->p3 = p12;
  516.           if (anker == NULL)
  517.         anker = tp;
  518.           else
  519.         tp2->next = tp;
  520.           tp2 = tp;
  521.         }
  522.       p11 = p12;
  523.     }
  524.       else if (p11->s == p21->s)
  525.     {
  526.       if (fabs (p11->s - p12->s) < fabs (p21->s - p22->s))
  527.         {
  528.           tp = calloc (1, sizeof (struct triangle));
  529.           if (tp != NULL)
  530.         {
  531.           tp->p1 = p11;
  532.           tp->p2 = p21;
  533.           tp->p3 = p12;
  534.           if (anker == NULL)
  535.             anker = tp;
  536.           else
  537.             tp2->next = tp;
  538.           tp2 = tp;
  539.         }
  540.           p11 = p12;
  541.         }
  542.       else
  543.         {
  544.           tp = calloc (1, sizeof (struct triangle));
  545.           if (tp != NULL)
  546.         {
  547.           tp->p1 = p21;
  548.           tp->p2 = p22;
  549.           tp->p3 = p11;
  550.           if (anker == NULL)
  551.             anker = tp;
  552.           else
  553.             tp2->next = tp;
  554.           tp2 = tp;
  555.         }
  556.           p21 = p22;
  557.         }
  558.     }
  559.       else if (p11->s < p21->s)
  560.     {
  561.       tp = calloc (1, sizeof (struct triangle));
  562.       if (tp != NULL)
  563.         {
  564.           tp->p1 = p11;
  565.           tp->p2 = p21;
  566.           tp->p3 = p12;
  567.           if (anker == NULL)
  568.         anker = tp;
  569.           else
  570.         tp2->next = tp;
  571.           tp2 = tp;
  572.         }
  573.       p11 = p12;
  574.  
  575.     }
  576.       else if (p11->s > p21->s)
  577.     {
  578.       tp = calloc (1, sizeof (struct triangle));
  579.       if (tp != NULL)
  580.         {
  581.           tp->p1 = p21;
  582.           tp->p2 = p22;
  583.           tp->p3 = p11;
  584.           if (anker == NULL)
  585.         anker = tp;
  586.           else
  587.         tp2->next = tp;
  588.           tp2 = tp;
  589.         }
  590.       p21 = p22;
  591.  
  592.     }            /* big if-cascade ;) */
  593.  
  594.     }                /* while */
  595.  
  596.   *result = anker;
  597.   return (0);
  598.  
  599. }                /* triangulate */
  600.  
  601.  
  602. /********************************************/
  603. /* writepovheader:                          */
  604. /*                                          */
  605. /********************************************/
  606. void
  607. writepovheader (FILE * fp)
  608. {
  609.  
  610.   fprintf (fp, "/* POV-Scenefile generated by Shelly1.5           */\n");
  611.   fprintf (fp, "/* by RANDi: (rschultz@informatik.uni-rostock.de) */\n");
  612.  
  613.   fprintf (fp, "#declare te = pigment { color red 1 green 0 blue 0 }\n");
  614.  
  615.   fprintf (fp, "camera\n{\n location  <%.1f,%.1f,%.1f>\n", camx, camy, camz);
  616.   fprintf (fp, " look_at <0, 0, 0>\n}\n");
  617.  
  618.   fprintf (fp, "object\n{\n light_source {\n");
  619.   fprintf (fp, "  <250, 500, 500> color red 1 green 1 blue 1\n }\n");
  620.   fprintf (fp, "}\n");
  621.   fprintf (fp, "object\n{\n light_source {\n");
  622.   fprintf (fp, "  <-250, 500, 500> color red 1 green 1 blue 1\n }\n");
  623.   fprintf (fp, "}\n");
  624.  
  625. }                /* writepovheader */
  626.  
  627.  
  628. /********************************************/
  629. /* writepovtriangles:                       */
  630. /********************************************/
  631. int
  632. writepovtriangles (FILE * fp, struct punkt *anker1, struct punkt *anker2, int mode)
  633. {
  634.   struct punkt *p11, *p12, *p21, *p22;
  635.   struct triangle *tp, *tp1, *tp2;
  636.  
  637.   if ((anker1 == NULL) || (anker2 == NULL))
  638.     return (0);
  639.  
  640.   if (mode == 1)
  641.     {
  642.       triangulate (anker1, anker2, &tp);
  643.  
  644.       tp1 = tp;
  645.       while (tp1 != NULL)
  646.     {
  647.  
  648.       fprintf (fp, "triangle{<%.2f,%.2f,%.2f><%.2f,%.2f,%.2f><%.2f,%.2f,%.2f>\n", tp1->p1->x, tp1->p1->y, tp1->p1->z, tp1->p2->x, tp1->p2->y, tp1->p2->z, tp1->p3->x, tp1->p3->y, tp1->p3->z);
  649.       fprintf (fp, "pigment{te}}\n");
  650.  
  651.       tp2 = tp1->next;
  652.  
  653.       free (tp1);
  654.  
  655.       tp1 = tp2;
  656.     }            /* while */
  657.  
  658.       return (0);
  659.     };
  660.  
  661.  
  662.   p11 = anker1;
  663.   p12 = p11;
  664.   p21 = anker2;
  665.   p22 = p21;
  666.  
  667.   do
  668.     {
  669.       p11 = p12;
  670.       p21 = p22;
  671.       p12 = (*p11).next;
  672.       p22 = (*p21).next;
  673.  
  674.       if ((p12 != NULL) && (p22 != NULL))
  675.     {
  676.       fprintf (fp, "triangle{<%.2f,%.2f,%.2f><%.2f,%.2f,%.2f><%.2f,%.2f,%.2f>\n", (*p11).x, (*p11).y, (*p11).z, (*p12).x, (*p12).y, (*p12).z, (*p21).x, (*p21).y, (*p21).z);
  677.       fprintf (fp, "pigment{te}}\n");
  678.  
  679.       fprintf (fp, "triangle{<%.2f,%.2f,%.2f><%.2f,%.2f,%.2f><%.2f,%.2f,%.2f>\n", (*p21).x, (*p21).y, (*p21).z, (*p12).x, (*p12).y, (*p12).z, (*p22).x, (*p22).y, (*p22).z);
  680.       fprintf (fp, "pigment{te}}\n");
  681.     }
  682.     }
  683.   while ((p12 != NULL) && (p22 != NULL));
  684.  
  685.   return (0);
  686. }                /* writepovtriangles */
  687.  
  688.  
  689. /********************************************/
  690. /* writepovfinish:                          */
  691. /********************************************/
  692. void
  693. writepovfinish (FILE * fptemp, FILE * fp)
  694. {
  695.  
  696.   filecopy (fptemp, fp);
  697.  
  698. }
  699.  
  700.  
  701. /********************************************/
  702. /* writerplline:                            */
  703. /********************************************/
  704. int
  705. writerplline (FILE * fp, struct punkt *anker1, struct punkt *anker2, int mode)
  706. {
  707.   struct punkt *p11, *p12;
  708.   struct triangle *tp1, *tp2, *tp;
  709.  
  710.   if (mode == 1)
  711.     {
  712.       triangulate (anker1, anker2, &tp);
  713.  
  714.       tp1 = tp;
  715.       while (tp1 != NULL)
  716.     {
  717.       fprintf (fp, "%.3f %.3f %.3f\n%.3f %.3f %.3f\n%.3f %.3f %.3f\n", tp1->p1->x / 100.0, tp1->p1->y / 100.0, tp1->p1->z / 100.0, tp1->p2->x / 100.0, tp1->p2->y / 100.0, tp1->p2->z / 100.0, tp1->p3->x / 100.0, tp1->p3->y / 100.0, tp1->p3->z / 100.0);
  718.       fprintf (fp, "0 0 0\n3\n0 0 255 0\n\"Triangle\"\n0\n\"CEND\"\nC_POLYGON DROP\n");
  719.  
  720.       tp2 = tp1->next;
  721.  
  722.       free (tp1);
  723.  
  724.       tp1 = tp2;
  725.     }            /* while */
  726.  
  727.       return (0);
  728.     };
  729.  
  730.   if (anker1 == NULL)
  731.     return (0);
  732.  
  733.   p11 = anker1;
  734.   p12 = p11;
  735.  
  736.   countw++;            /* calc number of lines created */
  737.  
  738.   fprintf (fp, "%.3f  %.3f  %.3f\n", (*p11).x / 100.0, (*p11).y / 100.0, (*p11).z / 100.0);
  739.  
  740.   do
  741.     {
  742.       p11 = p12;
  743.       p12 = (*p11).next;
  744.  
  745.       if (p12 != NULL)
  746.     {
  747.       fprintf (fp, "%.3f  %.3f  %.3f\n", (*p12).x / 100.0, (*p12).y / 100.0, (*p12).z / 100.0);
  748.     }
  749.     }
  750.   while (p12 != NULL);
  751.  
  752.   return (0);
  753. }                /* writerplline */
  754.  
  755.  
  756. /********************************************/
  757. /* writerplfinish:                          */
  758. /*                                          */
  759. /********************************************/
  760. void
  761. writerplfinish (FILE * fptemp, FILE * fp, int mode)
  762. {
  763.  
  764.   filecopy (fptemp, fp);
  765.  
  766.   if (mode == 0)
  767.     {
  768.       fprintf (fp, "%d\n", counth);    /* height width of the mesh */
  769.       fprintf (fp, "%d\n", countw);
  770.  
  771.       fprintf (fp, "3\n0\n255 255 255 0\n");    /* RGBA */
  772.       fprintf (fp, "\"Shell\"\n0\n");    /* Name */
  773.       fprintf (fp, "\"CEND\"\n");
  774.       fprintf (fp, "C_MESH DROP\n");
  775.     }                /* if */
  776. }                /* writerplfinish */
  777.  
  778. /********************************************/
  779. /* writex3dheader:                          */
  780. /*                                          */
  781. /********************************************/
  782. void
  783. writex3dheader (FILE * fp)
  784. {
  785.  
  786.   fprintf (fp, "2\n");        /* Number of Colors */
  787.   fprintf (fp, "0  0 0 0\n");    /* Color 0 Black */
  788.   fprintf (fp, "1  255 0 0\n");    /* Color 1 Red */
  789.  
  790. }                /* writex3dheader */
  791.  
  792.  
  793. /********************************************/
  794. /* new_pnode:                               */
  795. /*                                          */
  796. /********************************************/
  797. void
  798. new_pnode (struct pmerk **anker, struct punkt *p1)
  799. {
  800.   struct pmerk *mp;
  801.  
  802.   if ((mp = calloc (1, sizeof (struct pmerk))) != NULL)
  803.     {
  804.       mp->x = p1->x;
  805.       mp->y = p1->y;
  806.       mp->z = p1->z;
  807.       mp->id = countp;
  808.       mp->next = *anker;
  809.       *anker = mp;
  810.     }
  811.   else
  812.     return;
  813.  
  814. }                /* new_pnode */
  815.  
  816. /********************************************/
  817. /* free_pmerk_list:                         */
  818. /*                                          */
  819. /********************************************/
  820. void
  821. free_pmerk_list (struct pmerk *anker)
  822. {
  823.   struct pmerk *mp1 = anker, *mp2;
  824.  
  825.   while (mp1 != NULL)
  826.     {
  827.       mp2 = mp1->next;
  828.       free (mp1);
  829.       mp1 = mp2;
  830.     }                /* while */
  831.  
  832. }                /* free_pmerk_list */
  833.  
  834. /********************************************/
  835. /* is_p_in:                                 */
  836. /*                                          */
  837. /********************************************/
  838. int
  839. is_p_in (struct pmerk *anker, struct punkt *p)
  840. {
  841.   struct pmerk *mp1 = anker, *mp2;
  842.  
  843.   while (mp1 != NULL)
  844.     {
  845.       if (mp1->x == p->x)
  846.     if (mp1->y == p->y)
  847.       if (mp1->z == p->z)
  848.         return (mp1->id);
  849.  
  850.       mp2 = mp1->next;
  851.       mp1 = mp2;
  852.     }
  853.   return (0);
  854. }                /* is_p_in */
  855.  
  856.  
  857. /********************************************/
  858. /* new_lnode:                               */
  859. /*                                          */
  860. /********************************************/
  861. void
  862. new_lnode (struct lmerk **anker, int id1, int id2)
  863. {
  864.   struct lmerk *lp, *lp1 = *anker, *lp2;
  865.  
  866.   if (lp1 == NULL)
  867.     {
  868.       if ((lp = calloc (1, sizeof (struct lmerk))) != NULL)
  869.     {
  870.       lp->id1 = id1;
  871.       lp->id2 = id2;
  872.       lp->id = countl;
  873.       *anker = lp;
  874.     }
  875.       else
  876.     return;
  877.     }
  878.  
  879.   while (lp1 != NULL)
  880.     {
  881.       lp2 = lp1->next;
  882.       if (lp2 == NULL)
  883.     if ((lp = calloc (1, sizeof (struct lmerk))) != NULL)
  884.       {
  885.         lp->id1 = id1;
  886.         lp->id2 = id2;
  887.         lp->id = countl;
  888.         lp1->next = lp;
  889.       }
  890.     else
  891.       return;
  892.  
  893.       lp1 = lp2;
  894.     }
  895.  
  896. }                /* new_lnode */
  897.  
  898.  
  899. /********************************************/
  900. /* app_llist:                               */
  901. /*                                          */
  902. /********************************************/
  903. void
  904. app_llist (struct lmerk *anker, struct lmerk *list)
  905. {
  906.   struct lmerk *lp1 = anker, *lp2;
  907.  
  908.   while (lp1 != NULL)
  909.     {
  910.       lp2 = lp1->next;
  911.       if (lp2 == NULL)
  912.     lp1->next = list;
  913.       lp1 = lp2;
  914.     }
  915.   return;
  916. }                /* app_llist */
  917.  
  918. /********************************************/
  919. /* free_lmerk_list:                         */
  920. /*                                          */
  921. /********************************************/
  922. void
  923. free_lmerk_list (struct lmerk *anker)
  924. {
  925.   struct lmerk *mp1 = anker, *mp2;
  926.  
  927.   while (mp1 != NULL)
  928.     {
  929.       mp2 = mp1->next;
  930.       free (mp1);
  931.       mp1 = mp2;
  932.     }                /* while */
  933.  
  934. }                /* free_lmerk_list */
  935.  
  936. /********************************************/
  937. /* is_l_in:                                 */
  938. /*                                          */
  939. /********************************************/
  940. int
  941. is_l_in (struct lmerk *anker, int id1, int id2)
  942. {
  943.   struct lmerk *mp1 = anker, *mp2;
  944.  
  945.   while (mp1 != NULL)
  946.     {
  947.       if (mp1->id1 == id1)
  948.     if (mp1->id2 == id2)
  949.       return (mp1->id);
  950.  
  951.       if (mp1->id2 == id1)
  952.     if (mp1->id1 == id2)
  953.       return (mp1->id);
  954.  
  955.       mp2 = mp1->next;
  956.       mp1 = mp2;
  957.     }
  958.   return (0);
  959. }                /* is_l_in */
  960.  
  961.  
  962. /********************************************/
  963. /* new_tnode:                               */
  964. /*                                          */
  965. /********************************************/
  966. void
  967. new_tnode (struct tmerk **anker, int id1, int id2, int id3)
  968. {
  969.   struct tmerk *tp, *tp1 = *anker, *tp2;
  970.   if (tp1 == NULL)
  971.     if ((tp = calloc (1, sizeof (struct tmerk))) != NULL)
  972.       {
  973.     tp->lid1 = id1;
  974.     tp->lid2 = id2;
  975.     tp->lid3 = id3;
  976.     *anker = tp;
  977.       }
  978.     else
  979.       return;
  980.   while (tp1 != NULL)
  981.     {
  982.       tp2 = tp1->next;
  983.       if (tp2 == NULL)
  984.     if ((tp = calloc (1, sizeof (struct tmerk))) != NULL)
  985.       {
  986.         tp->lid1 = id1;
  987.         tp->lid2 = id2;
  988.         tp->lid3 = id3;
  989.         tp1->next = tp;
  990.       }
  991.     else
  992.       return;
  993.       tp1 = tp2;
  994.     }
  995.  
  996. }                /* new_tnode */
  997.  
  998. /********************************************/
  999. /* free_tmerk_list:                         */
  1000. /*                                          */
  1001. /********************************************/
  1002. void
  1003. free_tmerk_list (struct tmerk *anker)
  1004. {
  1005.   struct tmerk *tp1 = anker, *tp2;
  1006.  
  1007.   while (tp1 != NULL)
  1008.     {
  1009.       tp2 = tp1->next;
  1010.       free (tp1);
  1011.       tp1 = tp2;
  1012.     }                /* while */
  1013.  
  1014. }                /* free_tmerk_list */
  1015.  
  1016.  
  1017. /********************************************/
  1018. /* writex3dline:                            */
  1019. /********************************************/
  1020. int
  1021. writex3dline (FILE * fp, struct punkt *anker1, struct punkt *anker2, int mode)
  1022. {
  1023.   struct punkt *p11, *p12;
  1024.   struct triangle *tp, *tp1, *tp2;
  1025.  
  1026.   static struct pmerk *plist1 = NULL;
  1027.   struct pmerk *plist2 = NULL;
  1028.   static struct lmerk *llist1 = NULL;
  1029.   struct lmerk *llist2 = NULL;
  1030.  
  1031.   static int called = 0, count = 0;
  1032.   int pid1, pid2, pid3;
  1033.   int lid1, lid2, lid3;
  1034.  
  1035.   if (mode == 2)
  1036.     {
  1037.       free_pmerk_list (plist1);
  1038.       return (0);
  1039.     };
  1040.  
  1041.   if (mode == 1)
  1042.     {
  1043.       triangulate (anker1, anker2, &tp);
  1044.  
  1045.       tp1 = tp;
  1046.       while (tp1 != NULL)
  1047.     {
  1048.       if (((pid1 = is_p_in (plist2, tp1->p1)) == 0) && ((pid1 = is_p_in (plist1, tp1->p1)) == 0))
  1049.         {
  1050.           fprintf (fp, "%d %.3f %.3f %.3f\n", countp, tp1->p1->x, tp1->p1->y, tp1->p1->z);
  1051.           new_pnode (&plist2, tp1->p1);
  1052.           pid1 = countp;
  1053.           countp++;
  1054.         }
  1055.  
  1056.       if (((pid2 = is_p_in (plist2, tp1->p2)) == 0) && ((pid2 = is_p_in (plist1, tp1->p2)) == 0))
  1057.         {
  1058.           fprintf (fp, "%d %.3f %.3f %.3f\n", countp, tp1->p2->x, tp1->p2->y, tp1->p2->z);
  1059.           new_pnode (&plist2, tp1->p2);
  1060.           pid2 = countp;
  1061.           countp++;
  1062.         }
  1063.  
  1064.       if (((pid3 = is_p_in (plist2, tp1->p3)) == 0) && ((pid3 = is_p_in (plist1, tp1->p3)) == 0))
  1065.         {
  1066.           fprintf (fp, "%d %.3f %.3f %.3f\n", countp, tp1->p3->x, tp1->p3->y, tp1->p3->z);
  1067.           new_pnode (&plist2, tp1->p3);
  1068.           pid3 = countp;
  1069.           countp++;
  1070.         }
  1071.  
  1072.       if (((lid1 = is_l_in (llist2, pid1, pid2)) == 0) && ((lid1 = is_l_in (llist1, pid1, pid2)) == 0))
  1073.         {
  1074.           new_lnode (&llist2, pid1, pid2);
  1075.           lid1 = countl;
  1076.           countl++;
  1077.         }
  1078.  
  1079.       if (((lid2 = is_l_in (llist2, pid2, pid3)) == 0) && ((lid2 = is_l_in (llist1, pid2, pid3)) == 0))
  1080.         {
  1081.           new_lnode (&llist2, pid2, pid3);
  1082.           lid2 = countl;
  1083.           countl++;
  1084.         }
  1085.  
  1086.       if (((lid3 = is_l_in (llist2, pid3, pid1)) == 0) && ((lid3 = is_l_in (llist1, pid3, pid1)) == 0))
  1087.         {
  1088.           new_lnode (&llist2, pid3, pid1);
  1089.           lid3 = countl;
  1090.           countl++;
  1091.         }
  1092.  
  1093.       new_tnode (&bigtlist, lid1, lid2, lid3);
  1094.       countt++;
  1095.  
  1096.       tp2 = tp1->next;
  1097.       free (tp1);
  1098.       tp1 = tp2;
  1099.     }            /* while */
  1100.  
  1101.  
  1102.       free_pmerk_list (plist1);
  1103.       plist1 = plist2;
  1104.  
  1105.       if (called == 0)
  1106.     bigllist = llist2;
  1107.       else
  1108.     app_llist (llist1, llist2);
  1109.       llist1 = llist2;
  1110.  
  1111.       called = 1;
  1112.       return (0);
  1113.     };
  1114.  
  1115.  
  1116.  
  1117.   if (anker1 == NULL)
  1118.     return (0);
  1119.  
  1120.   if (called == 0)
  1121.     {
  1122.       called = 1;
  1123.       count = -1;
  1124.       countw = 0;
  1125.     }
  1126.   countw++;
  1127.  
  1128.   p11 = anker1;
  1129.   p12 = p11;
  1130.  
  1131.   fprintf (fp, "%d  %.3f %.3f %.3f\n", ++count, (*p11).x, (*p11).y, (*p11).z);
  1132.  
  1133.   do
  1134.     {
  1135.       p11 = p12;
  1136.       p12 = (*p11).next;
  1137.  
  1138.       if (p12 != NULL)
  1139.     {
  1140.       fprintf (fp, "%d  %.3f %.3f %.3f\n", ++count, (*p12).x, (*p12).y, (*p12).z);
  1141.     }
  1142.     }
  1143.   while (p12 != NULL);
  1144.  
  1145.   return (0);
  1146. }                /* writex3dline */
  1147.  
  1148. /********************************************/
  1149. /* writex3dfinish:                          */
  1150. /*                                          */
  1151. /********************************************/
  1152. void
  1153. writex3dfinish (FILE * fptemp, FILE * fp, int mode)
  1154. {
  1155.   int edges = 0, faces = 0, edgecount = 0, facecount = 0, a = 0, b = 0,
  1156.     r = 0, r2 = 0, r3 = 0;
  1157.   int point1 = 0, point2 = 0, edge1 = 0, edge2 = 0, edge3 = 0;
  1158.   struct tmerk *tp1 = bigtlist, *tp2;
  1159.   struct lmerk *lp1 = bigllist, *lp2;
  1160.  
  1161.   fprintf (stdout, "\nWriting additional X3D-Data ...");
  1162.  
  1163.   fprintf (fp, "%d\n", countp);    /* Number of points */
  1164.  
  1165.   filecopy (fptemp, fp);
  1166.  
  1167.   if (mode == 1)
  1168.     {
  1169.       edges = countl;
  1170.       fprintf (fp, "%d\n", edges);
  1171.  
  1172.       while (lp1 != NULL)
  1173.     {
  1174.       fprintf (fp, "%d 1 %d %d\n", edgecount++, lp1->id1, lp1->id2);
  1175.       lp2 = lp1->next;
  1176.       free (lp1);
  1177.       lp1 = lp2;
  1178.     }
  1179.  
  1180.       faces = countt;
  1181.       fprintf (fp, "%d\n", faces);
  1182.  
  1183.       while (tp1 != NULL)
  1184.     {
  1185.       fprintf (fp, "%d 1 3 %d %d %d\n", facecount++, tp1->lid1, tp1->lid2, tp1->lid3);
  1186.       tp2 = tp1->next;
  1187.       free (tp1);
  1188.       tp1 = tp2;
  1189.     }
  1190.  
  1191.       return;
  1192.     }
  1193.  
  1194.   edges = (counth * (countw - 1) + countw * (counth - 1) + (counth - 1) * (countw - 1));
  1195.   /* number of edges! */
  1196.   fprintf (fp, "%d\n", edges);
  1197.  
  1198.  
  1199.   /* write horizontal edges */
  1200.   for (a = 0; a < counth; a++)
  1201.     {
  1202.       r = a;
  1203.       for (b = 0; b < (countw - 1); b++)
  1204.     {
  1205.       point1 = r;
  1206.       point2 = r + counth;
  1207.       fprintf (fp, "%d  1   %d %d\n", edgecount++, point1, point2);
  1208.       r = r + counth;
  1209.     }
  1210.     }
  1211.   /* write vertical edges */
  1212.   for (a = 0; a < countw; a++)
  1213.     {
  1214.       r = a * counth;
  1215.       for (b = 0; b < (counth - 1); b++)
  1216.     {
  1217.       point1 = r + b;
  1218.       point2 = r + b + 1;
  1219.       fprintf (fp, "%d  1   %d %d\n", edgecount++, point1, point2);
  1220.     }
  1221.     }
  1222.   /* write diagonal edges */
  1223.   for (a = 0; a < counth - 1; a++)
  1224.     {
  1225.       r = a;
  1226.       for (b = 0; b < (countw - 1); b++)
  1227.     {
  1228.       point1 = r;
  1229.       point2 = r + counth + 1;
  1230.       fprintf (fp, "%d  1   %d %d\n", edgecount++, point1, point2);
  1231.       r = r + counth;
  1232.     }
  1233.     }
  1234.   /* ohhh boy, THIS (^^^) took me time ! :), now to that faces! */
  1235.  
  1236.   /* write faces */
  1237.  
  1238.   faces = 2 * (countw - 1) * (counth - 1);
  1239.  
  1240.   fprintf (fp, "%d\n", faces);    /* number of faces/polygons */
  1241.  
  1242.   r = 0;
  1243.   r3 = countw * (counth - 1) + counth * (countw - 1);
  1244.  
  1245.   for (a = 0; a < counth - 1; a++)
  1246.     {
  1247.       r2 = counth * (countw - 1) + a;
  1248.       for (b = 0; b < countw - 1; b++)
  1249.     {
  1250.       edge1 = r + countw - 1;
  1251.       edge2 = r2;
  1252.       edge3 = r3;
  1253.       fprintf (fp, "%d  1  3  %d %d %d\n", facecount++, edge1, edge2, edge3);
  1254.  
  1255.       edge1 = r;
  1256.       edge2 = r2 + counth - 1;
  1257.       edge3 = r3;
  1258.       fprintf (fp, "%d  1  3  %d %d %d\n", facecount++, edge1, edge2, edge3);
  1259.  
  1260.       r++;
  1261.       r2 = r2 + counth - 1;
  1262.       r3++;
  1263.     }
  1264.     }
  1265.  
  1266.  
  1267. }                /* writex3dfinish */
  1268.  
  1269.  
  1270. /********************************************/
  1271. /* writet3dheader:                          */
  1272. /*                                          */
  1273. /********************************************/
  1274. void
  1275. writet3dheader (FILE * fp)
  1276. {
  1277.   char percent = '%';
  1278.  
  1279.   fprintf (fp, " %c T3Dlib-data-file generated by Shelly1.5\n", percent);
  1280.   fprintf (fp, " %c the ShellShapeGenerator by RANDi :    \n", percent);
  1281.   fprintf (fp, " %c (rschultz@informatik.uni-rostock.de)\n", percent);
  1282.  
  1283.   fprintf (fp, "OBJ Begin \"Hierarchy 1\"\n");
  1284.   fprintf (fp, " DESC Begin \"Object 1 at level 1 of hierarchy 1\"\n");
  1285.   fprintf (fp, "  NAME \"SHELL\"\n");
  1286.   fprintf (fp, "  SHAP Shape = 2\n");
  1287.   fprintf (fp, "  SHAP Lamp  = 0\n");
  1288.   fprintf (fp, "  POSI X=0 Y=0 Z=0\n");
  1289.   fprintf (fp, "  AXIS XAxis X=1 Y=0 Z=0\n");
  1290.   fprintf (fp, "  AXIS YAxis X=0 Y=1 Z=0\n");
  1291.   fprintf (fp, "  AXIS ZAxis X=0 Y=0 Z=1\n");
  1292.   fprintf (fp, "  SIZE X=32 Y=32 Z=32\n");
  1293.  
  1294. }                /* writet3dheader */
  1295.  
  1296.  
  1297. /********************************************/
  1298. /* writet3dline:                            */
  1299. /********************************************/
  1300. int
  1301. writet3dline (FILE * fp, struct punkt *anker1, struct punkt *anker2, int mode)
  1302. {
  1303.   struct punkt *p11, *p12;
  1304.   struct triangle *tp, *tp1, *tp2;
  1305.   static int called = 0, count = 0;
  1306.  
  1307.   static struct pmerk *plist1 = NULL;
  1308.   struct pmerk *plist2 = NULL;
  1309.   static struct lmerk *llist1 = NULL;
  1310.   struct lmerk *llist2 = NULL;
  1311.  
  1312.  
  1313.   int pid1, pid2, pid3;
  1314.   int lid1, lid2, lid3;
  1315.  
  1316.   if ((anker1 == NULL) && (anker2 == NULL))
  1317.     return (5);
  1318.  
  1319.   if (mode == 2)
  1320.     {
  1321.       free_pmerk_list (plist1);
  1322.       return (0);
  1323.     };
  1324.  
  1325.   if (mode == 1)
  1326.     {
  1327.       triangulate (anker1, anker2, &tp);
  1328.  
  1329.       tp1 = tp;
  1330.       while (tp1 != NULL)
  1331.     {
  1332.       if (((pid1 = is_p_in (plist2, tp1->p1)) == 0) && ((pid1 = is_p_in (plist1, tp1->p1)) == 0))
  1333.         {
  1334.           fprintf (fp, "  PNTS Point[%d] X=%.3f Y=%.3f Z=%.3f\n", countp, tp1->p1->x, tp1->p1->y, tp1->p1->z);
  1335.           new_pnode (&plist2, tp1->p1);
  1336.           pid1 = countp;
  1337.           countp++;
  1338.         }
  1339.  
  1340.       if (((pid2 = is_p_in (plist2, tp1->p2)) == 0) && ((pid2 = is_p_in (plist1, tp1->p2)) == 0))
  1341.         {
  1342.           fprintf (fp, "  PNTS Point[%d] X=%.3f Y=%.3f Z=%.3f\n", countp, tp1->p2->x, tp1->p2->y, tp1->p2->z);
  1343.           new_pnode (&plist2, tp1->p2);
  1344.           pid2 = countp;
  1345.           countp++;
  1346.         }
  1347.  
  1348.       if (((pid3 = is_p_in (plist2, tp1->p3)) == 0) && ((pid3 = is_p_in (plist1, tp1->p3)) == 0))
  1349.         {
  1350.           fprintf (fp, "  PNTS Point[%d] X=%.3f Y=%.3f Z=%.3f\n", countp, tp1->p3->x, tp1->p3->y, tp1->p3->z);
  1351.           new_pnode (&plist2, tp1->p3);
  1352.           pid3 = countp;
  1353.           countp++;
  1354.         }
  1355.  
  1356.       if (((lid1 = is_l_in (llist2, pid1, pid2)) == 0) && ((lid1 = is_l_in (llist1, pid1, pid2)) == 0))
  1357.         {
  1358.           new_lnode (&llist2, pid1, pid2);
  1359.           lid1 = countl;
  1360.           countl++;
  1361.         }
  1362.  
  1363.       if (((lid2 = is_l_in (llist2, pid2, pid3)) == 0) && ((lid2 = is_l_in (llist1, pid2, pid3)) == 0))
  1364.         {
  1365.           new_lnode (&llist2, pid2, pid3);
  1366.           lid2 = countl;
  1367.           countl++;
  1368.         }
  1369.  
  1370.       if (((lid3 = is_l_in (llist2, pid3, pid1)) == 0) && ((lid3 = is_l_in (llist1, pid3, pid1)) == 0))
  1371.         {
  1372.           new_lnode (&llist2, pid3, pid1);
  1373.           lid3 = countl;
  1374.           countl++;
  1375.         }
  1376.  
  1377.       new_tnode (&bigtlist, lid1, lid2, lid3);
  1378.       countt++;
  1379.  
  1380.       tp2 = tp1->next;
  1381.       free (tp1);
  1382.       tp1 = tp2;
  1383.     }            /* while */
  1384.  
  1385.  
  1386.       free_pmerk_list (plist1);
  1387.       plist1 = plist2;
  1388.  
  1389.       if (called == 0)
  1390.     bigllist = llist2;
  1391.       else
  1392.     app_llist (llist1, llist2);
  1393.       llist1 = llist2;
  1394.  
  1395.       called = 1;
  1396.       return (0);
  1397.     };
  1398.  
  1399.  
  1400.   if (anker1 == NULL)
  1401.     return (0);
  1402.  
  1403.   if (called == 0)
  1404.     {
  1405.       called = 1;
  1406.       count = -1;
  1407.       countw = 0;
  1408.     }
  1409.   countw++;
  1410.  
  1411.   p11 = anker1;
  1412.   p12 = p11;
  1413.  
  1414.   fprintf (fp, "  PNTS Point[%d] X=%.3f Y=%.3f Z=%.3f\n", ++count, (*p11).x, (*p11).y, (*p11).z);
  1415.  
  1416.   do
  1417.     {
  1418.       p11 = p12;
  1419.       p12 = (*p11).next;
  1420.  
  1421.       if (p12 != NULL)
  1422.     {
  1423.       fprintf (fp, "  PNTS Point[%d] X=%.3f Y=%.3f Z=%.3f\n", ++count, (*p12).x, (*p12).y, (*p12).z);
  1424.     }
  1425.     }
  1426.   while (p12 != NULL);
  1427.  
  1428.   return (0);
  1429. }                /* writet3dline */
  1430.  
  1431.  
  1432. /********************************************/
  1433. /* writet3dfinish:                          */
  1434. /*                                          */
  1435. /********************************************/
  1436. void
  1437. writet3dfinish (FILE * fptemp, FILE * fp, int mode)
  1438. {
  1439.   int edges = 0, faces = 0, edgecount = 0, facecount = 0, a = 0, b = 0,
  1440.     r = 0, r2 = 0, r3 = 0;
  1441.   int point1 = 0, point2 = 0, edge1 = 0, edge2 = 0, edge3 = 0;
  1442.   struct tmerk *tp1 = bigtlist, *tp2;
  1443.   struct lmerk *lp1 = bigllist, *lp2;
  1444.  
  1445.  
  1446.   fprintf (stdout, "\nWriting additional T3Dlib-Data ...");
  1447.  
  1448.   fprintf (fp, "  PNTS PCount %d\n", countp);
  1449.  
  1450.   filecopy (fptemp, fp);
  1451.  
  1452.   if (mode == 1)
  1453.     {
  1454.       edges = countl;
  1455.       fprintf (fp, "  EDGE ECount %d\n", edges);
  1456.  
  1457.       while (lp1 != NULL)
  1458.     {
  1459.       fprintf (fp, "  EDGE Edge[%d] %d %d\n", edgecount++, lp1->id1, lp1->id2);
  1460.       lp2 = lp1->next;
  1461.       free (lp1);
  1462.       lp1 = lp2;
  1463.     }
  1464.  
  1465.       faces = countt;
  1466.       fprintf (fp, "  FACE TCount %d\n", faces);
  1467.  
  1468.       while (tp1 != NULL)
  1469.     {
  1470.       fprintf (fp, "  FACE Connect[%d] %d %d %d\n", facecount++, tp1->lid1, tp1->lid2, tp1->lid3);
  1471.       tp2 = tp1->next;
  1472.       free (tp1);
  1473.       tp1 = tp2;
  1474.     }
  1475.  
  1476.       return;
  1477.     }
  1478.  
  1479.   edges = (counth * (countw - 1) + countw * (counth - 1) + (counth - 1) * (countw - 1));
  1480.   /* number of edges! */
  1481.   fprintf (fp, "  EDGE ECount %d\n", edges);
  1482.  
  1483.  
  1484.   /* write horizontal edges */
  1485.   for (a = 0; a < counth; a++)
  1486.     {
  1487.       r = a;
  1488.       for (b = 0; b < (countw - 1); b++)
  1489.     {
  1490.       point1 = r;
  1491.       point2 = r + counth;
  1492.       fprintf (fp, "  EDGE Edge[%d] %d %d\n", edgecount++, point1, point2);
  1493.       r = r + counth;
  1494.     }
  1495.     }
  1496.   /* write vertical edges */
  1497.   for (a = 0; a < countw; a++)
  1498.     {
  1499.       r = a * counth;
  1500.       for (b = 0; b < (counth - 1); b++)
  1501.     {
  1502.       point1 = r + b;
  1503.       point2 = r + b + 1;
  1504.       fprintf (fp, "  EDGE Edge[%d] %d %d\n", edgecount++, point1, point2);
  1505.     }
  1506.     }
  1507.   /* write diagonal edges */
  1508.   for (a = 0; a < counth - 1; a++)
  1509.     {
  1510.       r = a;
  1511.       for (b = 0; b < (countw - 1); b++)
  1512.     {
  1513.       point1 = r;
  1514.       point2 = r + counth + 1;
  1515.       fprintf (fp, "  EDGE Edge[%d] %d %d\n", edgecount++, point1, point2);
  1516.       r = r + counth;
  1517.     }
  1518.     }
  1519.   /* ohhh boy, THIS (^^^) took me time ! :), now to that faces! */
  1520.  
  1521.   /* write faces */
  1522.  
  1523.   faces = 2 * (countw - 1) * (counth - 1);
  1524.  
  1525.   fprintf (fp, "  FACE TCount %d\n", faces);
  1526.  
  1527.   r = 0;
  1528.   r3 = countw * (counth - 1) + counth * (countw - 1);
  1529.  
  1530.   for (a = 0; a < counth - 1; a++)
  1531.     {
  1532.       r2 = counth * (countw - 1) + a;
  1533.       for (b = 0; b < countw - 1; b++)
  1534.     {
  1535.       edge1 = r + countw - 1;
  1536.       edge2 = r2;
  1537.       edge3 = r3;
  1538.       fprintf (fp, "  FACE Connect[%d] %d %d %d\n", facecount++, edge1, edge2, edge3);
  1539.  
  1540.       edge1 = r;
  1541.       edge2 = r2 + counth - 1;
  1542.       edge3 = r3;
  1543.       fprintf (fp, "  FACE Connect[%d] %d %d %d\n", facecount++, edge1, edge2, edge3);
  1544.  
  1545.       r++;
  1546.       r2 = r2 + counth - 1;
  1547.       r3++;
  1548.     }
  1549.     }
  1550.  
  1551.   fprintf (fp, "  COLR R=98 G=68 B=58\n");
  1552.   fprintf (fp, "  REFL R=0 G=0 B=0\n");
  1553.   fprintf (fp, "  TRAN R=0 G=0 B=0\n");
  1554.   fprintf (fp, "  SPC1 R=0 G=0 B=0\n");
  1555.   fprintf (fp, "  End DESC   \"Object 1 at level 1 of hierarchy 1\"\n");
  1556.   fprintf (fp, " TOBJ       \"Object 0 at level 1 of hierarchy 1\"\n");
  1557.   fprintf (fp, "End OBJ  \"Hierarchy 1\"\n");
  1558.  
  1559. }                /* writet3dfinish */
  1560.  
  1561.  
  1562. /********************************************/
  1563. /* writerawtriangles:                       */
  1564. /********************************************/
  1565. int
  1566. writerawtriangles (FILE * fp, struct punkt *anker1, struct punkt *anker2, int mode)
  1567. {
  1568.   struct punkt *p11, *p12, *p21, *p22;
  1569.   struct triangle *tp, *tp1, *tp2;
  1570.  
  1571.   if ((anker1 == NULL) || (anker2 == NULL))
  1572.     return (0);
  1573.  
  1574.   if (mode == 1)
  1575.     {
  1576.       triangulate (anker1, anker2, &tp);
  1577.  
  1578.       tp1 = tp;
  1579.       while (tp1 != NULL)
  1580.     {
  1581.       fprintf (fp, "%.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f\n", tp1->p1->x, tp1->p1->y, tp1->p1->z, tp1->p2->x, tp1->p2->y, tp1->p2->z, tp1->p3->x, tp1->p3->y, tp1->p3->z);
  1582.       tp2 = tp1->next;
  1583.  
  1584.       free (tp1);
  1585.  
  1586.       tp1 = tp2;
  1587.     }            /* while */
  1588.  
  1589.       return (0);
  1590.     };
  1591.  
  1592.   p11 = anker1;
  1593.   p12 = p11;
  1594.   p21 = anker2;
  1595.   p22 = p21;
  1596.  
  1597.   do
  1598.     {
  1599.       p11 = p12;
  1600.       p21 = p22;
  1601.       p12 = (*p11).next;
  1602.       p22 = (*p21).next;
  1603.  
  1604.       if ((p12 != NULL) && (p22 != NULL))
  1605.     {
  1606.       fprintf (fp, "%.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f\n", (*p11).x, (*p11).y, (*p11).z, (*p12).x, (*p12).y, (*p12).z, (*p21).x, (*p21).y, (*p21).z);
  1607.  
  1608.       fprintf (fp, "%.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f\n", (*p21).x, (*p21).y, (*p21).z, (*p12).x, (*p12).y, (*p12).z, (*p22).x, (*p22).y, (*p22).z);
  1609.     }
  1610.     }
  1611.   while ((p12 != NULL) && (p22 != NULL));
  1612.  
  1613.   return (0);
  1614. }                /* writerawtriangles */
  1615.  
  1616. /********************************************/
  1617. /*calcg:                                    */
  1618. /********************************************/
  1619. double
  1620. calcg (double O, double N)
  1621. {
  1622.   if (N == 0)
  1623.     return (0);
  1624.   else
  1625.     return ((2 * pi) / N * (O * N / (2 * pi) - round (O * N / (2 * pi))));
  1626.  
  1627. }                /* calcg */
  1628.  
  1629.  
  1630. /********************************************/
  1631. /*calck:                                    */
  1632. /********************************************/
  1633. double
  1634. calck (struct ShellyArguments *ShellyArgs, double S, double O)
  1635. {
  1636.   static double N, N2, N3, L, L2, L3, W1, W2, W12, W13, W22, W23, P, P2,
  1637.     P3, Off2, Off3;
  1638.   double k = 0, g;
  1639.   static int called = 0;
  1640.  
  1641.  
  1642.  
  1643.   if (called == 0)
  1644.     {
  1645.  
  1646.       N = (*ShellyArgs).N;
  1647.       W1 = (*ShellyArgs).W1 * pi / 180;
  1648.       W2 = (*ShellyArgs).W2 * pi / 180;
  1649.       P = (*ShellyArgs).P * pi / 180;
  1650.       L = (*ShellyArgs).L;
  1651.  
  1652.       N2 = (*ShellyArgs).N2;
  1653.       W12 = (*ShellyArgs).W12 * pi / 180;
  1654.       W22 = (*ShellyArgs).W22 * pi / 180;
  1655.       P2 = (*ShellyArgs).P2 * pi / 180;
  1656.       L2 = (*ShellyArgs).L2;
  1657.  
  1658.       N3 = (*ShellyArgs).N3;
  1659.       W13 = (*ShellyArgs).W13 * pi / 180;
  1660.       W23 = (*ShellyArgs).W23 * pi / 180;
  1661.       P3 = (*ShellyArgs).P3 * pi / 180;
  1662.       L3 = (*ShellyArgs).L3;
  1663.  
  1664.       Off2 = (*ShellyArgs).Off2 * pi / 180;
  1665.       Off3 = (*ShellyArgs).Off3 * pi / 180;
  1666.  
  1667.     }
  1668.  
  1669.  
  1670.   g = calcg (O, N);
  1671.   if (N != 0)
  1672.     k = L * exp (-(2 * (S - P) / W1) * (2 * (S - P) / W1)) * exp (-(2 * g / W2) * (2 * g / W2));
  1673.  
  1674.   g = calcg (O + Off2, N2);
  1675.   if (N2 != 0)
  1676.     k = k + (L2 * exp (-(2 * (S - P2) / W12) * (2 * (S - P2) / W12)) * exp (-(2 * g / W22) * (2 * g / W22)));
  1677.  
  1678.   g = calcg (O + Off3, N3);
  1679.   if (N3 != 0)
  1680.     k = k + (L3 * exp (-(2 * (S - P3) / W13) * (2 * (S - P3) / W13)) * exp (-(2 * g / W23) * (2 * g / W23)));
  1681.  
  1682.   called = 1;
  1683.  
  1684.   return (k);
  1685. }                /* calck */
  1686.  
  1687.  
  1688. /********************************************/
  1689. /*innodule2:                                */
  1690. /********************************************/
  1691. double
  1692. innodule2 (struct ShellyArguments *ShellyArgs, double sc, double O, double S)
  1693. {
  1694.   double k1 = 0, k2 = 0;
  1695.  
  1696.   k1 = calck (ShellyArgs, S, O);
  1697.  
  1698.   k2 = calck (ShellyArgs, S + sc, O);
  1699.  
  1700.   return (fabs (k1) - fabs (k2));
  1701.  
  1702. }                /* innodule */
  1703.  
  1704.  
  1705. /********************************************/
  1706. /*innodule:                                 */
  1707. /********************************************/
  1708. double
  1709. innodule (struct ShellyArguments *ShellyArgs, double sc, double O)
  1710. {
  1711.   static double N, N2, N3, L, L2, L3, W2, W22, W23, Off2, Off3;
  1712.  
  1713.   double k1 = 0, k2 = 0, g;
  1714.   static int called = 0;
  1715.  
  1716.  
  1717.   if (called == 0)
  1718.     {
  1719.  
  1720.       N = (*ShellyArgs).N;
  1721.       W2 = (*ShellyArgs).W2 * pi / 180;
  1722.       L = (*ShellyArgs).L;
  1723.       N2 = (*ShellyArgs).N2;
  1724.       W22 = (*ShellyArgs).W22 * pi / 180;
  1725.       L2 = (*ShellyArgs).L2;
  1726.       N3 = (*ShellyArgs).N3;
  1727.       W23 = (*ShellyArgs).W23 * pi / 180;
  1728.       L3 = (*ShellyArgs).L3;
  1729.       Off2 = (*ShellyArgs).Off2 * pi / 180;
  1730.       Off3 = (*ShellyArgs).Off3 * pi / 180;
  1731.  
  1732.       called = 1;
  1733.     }
  1734.  
  1735.   g = calcg (O, N);
  1736.   if (N != 0)
  1737.     k1 = L * exp (-(2 * g / W2) * (2 * g / W2));
  1738.   g = calcg (O + Off2, N2);
  1739.   if (N2 != 0)
  1740.     k1 = k1 + (L2 * exp (-(2 * g / W22) * (2 * g / W22)));
  1741.   g = calcg (O + Off3, N3);
  1742.   if (N3 != 0)
  1743.     k1 = k1 + (L3 * exp (-(2 * g / W23) * (2 * g / W23)));
  1744.  
  1745.   g = calcg (O + sc, N);
  1746.   if (N != 0)
  1747.     k2 = L * exp (-(2 * g / W2) * (2 * g / W2));
  1748.   g = calcg (O + Off2 + sc, N2);
  1749.   if (N2 != 0)
  1750.     k2 = k2 + (L2 * exp (-(2 * g / W22) * (2 * g / W22)));
  1751.   g = calcg (O + Off3 + sc, N3);
  1752.   if (N3 != 0)
  1753.     k2 = k2 + (L3 * exp (-(2 * g / W23) * (2 * g / W23)));
  1754.  
  1755.  
  1756.   return (fabs (k1) - fabs (k2));
  1757.  
  1758. }                /* innodule */
  1759.  
  1760.  
  1761. /********************************************/
  1762. /*calccamera:                               */
  1763. /********************************************/
  1764. void
  1765. calccamera (double x, double y, double z)
  1766. {
  1767.   static double biggest;
  1768.  
  1769.  
  1770.   if ((fabs (x) > fabs (y)) && (fabs (x) > fabs (z)))
  1771.     if (fabs (x) > biggest)
  1772.       {
  1773.     biggest = fabs (x);
  1774.     camy = biggest * 1.5;
  1775.     camz = biggest * 1.5;
  1776.       }
  1777.   if ((fabs (y) > fabs (x)) && (fabs (y) > fabs (z)))
  1778.     if (fabs (y) > biggest)
  1779.       {
  1780.     biggest = fabs (y);
  1781.     camy = biggest * 1.5;
  1782.     camz = biggest * 1.5;
  1783.       }
  1784.  
  1785.   if ((fabs (z) > fabs (y)) && (fabs (z) > fabs (x)))
  1786.     if (fabs (z) > biggest)
  1787.       {
  1788.     biggest = fabs (z);
  1789.     camy = biggest * 1.5;
  1790.     camz = biggest * 1.5;
  1791.       }
  1792.  
  1793.  
  1794.  
  1795.  
  1796. }                /* calccamera */
  1797.  
  1798.  
  1799. /**********************************************/
  1800. /* CalcPoint:                                 */
  1801. /*                                            */
  1802. /**********************************************/
  1803. int
  1804. calcpoint (double O, double S, struct ShellyArguments *ShellyArgs, struct punkt **point)
  1805. {
  1806.   struct punkt *point1 = NULL;
  1807.   double x, y, z, R, Re, k;
  1808.   static double my;
  1809.   static double a, b, A, beta, phi, omega, alpha, Scale;
  1810.   static int called = 0;
  1811.  
  1812.   if (called == 0)
  1813.     {
  1814.       alpha = (*ShellyArgs).alpha * pi / 180;
  1815.       beta = (*ShellyArgs).beta * pi / 180;
  1816.       phi = (*ShellyArgs).phi * pi / 180;
  1817.       omega = (*ShellyArgs).omega * pi / 180;
  1818.       my = (*ShellyArgs).my * pi / 180;
  1819.  
  1820.       a = (*ShellyArgs).a;
  1821.       b = (*ShellyArgs).b;
  1822.       A = (*ShellyArgs).A;
  1823.  
  1824.       Scale = (*ShellyArgs).Scale;
  1825.       called = 1;
  1826.     }
  1827.   counth = 0;
  1828.  
  1829.   Re = pow ((pow (a, -2.0) * (cos (S) * cos (S)) + pow (b, -2.0) * (sin (S) * sin (S))), -0.5);
  1830.  
  1831.   k = calck (ShellyArgs, S, O);
  1832.  
  1833.   R = Re + k;
  1834.  
  1835.   /* alternatively: */
  1836.   /* R = pow((pow(a,2.0)*pow(cos(S),2.0)+pow(b,2.0)*pow(sin(S),2.0)),0.5); */
  1837.  
  1838.   x = Scale * (A * sin (beta) * cos (O) + R * cos (S + phi) * cos (O + omega) - R * sin (my) * sin (S + phi) * sin (O)) * exp (O * cot (alpha));
  1839.   y = Scale * (-1 * A * sin (beta) * sin (O) - R * cos (S + phi) * sin (O + omega) - R * sin (my) * sin (S + phi) * cos (O)) * exp (O * cot (alpha));
  1840.   z = Scale * (-1 * A * cos (beta) + R * sin (S + phi) * cos (my)) * exp (O * cot (alpha));
  1841.   if (camposspecified == NO)
  1842.     calccamera (x, y, z);
  1843.   if ((point1 = calloc (1, sizeof (struct punkt))) == NULL)
  1844.     {
  1845.       fprintf (stdout, "Shelly: NOT ENOUGH MEMORY!!! ... exiting ... !\n");
  1846.       return (5);
  1847.     }                /* if */
  1848.  
  1849.   (*point1).x = x;
  1850.   (*point1).y = y;
  1851.   (*point1).z = z;
  1852.   (*point1).s = S;
  1853.  
  1854.   *point = point1;
  1855.  
  1856.   return (0);
  1857.  
  1858. }                /* calcline */
  1859.  
  1860.  
  1861. /**********************************************/
  1862. /* calcnews:                                  */
  1863. /*             SSIA :)                        */
  1864. /**********************************************/
  1865. void
  1866. calcnews (struct ShellyArguments *SA, double O, double Sold, double *newS)
  1867. {
  1868.   double S = Sold, sd;
  1869.   int mittenodul = NO;
  1870.   sd = SA->sd * pi / 180;
  1871.  
  1872.   S += SA->Scans;
  1873.  
  1874.  
  1875.   while ((fabs (innodule2 (SA, S - Sold, O, Sold)) < SA->heightdiffs) && (S - Sold < sd) && (mittenodul == NO))
  1876.     {
  1877.       S += SA->Scans;
  1878.       if ((innodule2 (SA, SA->Scans, O, Sold) < 0) && (innodule2 (SA, SA->Scans, O, S) > 0))
  1879.     {
  1880.       mittenodul = YES;
  1881.     }
  1882.     }
  1883.  
  1884.   *newS = S;
  1885.  
  1886.   return;
  1887.  
  1888. }                /* calcnews */
  1889.  
  1890.  
  1891. /**********************************************/
  1892. /* CalcnodLine:                               */
  1893. /*                                            */
  1894. /**********************************************/
  1895. int
  1896. calcnodline (double O, struct ShellyArguments *ShellyArgs, struct punkt **list)
  1897. {
  1898.   struct punkt *list1 = NULL, *L1p1, *L1p2;
  1899.   double S, newS;
  1900.   static double sc;
  1901.   static double smin, smax, sd;
  1902.   static int called = 0;
  1903.  
  1904.   if (called == 0)
  1905.     {
  1906.       smin = (*ShellyArgs).smin * pi / 180;
  1907.       smax = (*ShellyArgs).smax * pi / 180;
  1908.       sd = (*ShellyArgs).sd * pi / 180;
  1909.  
  1910.       sc = (*ShellyArgs).Scans;
  1911.  
  1912.       called = 1;
  1913.     }
  1914.   S = smin;
  1915.  
  1916.   calcpoint (O, smin, ShellyArgs, &list1);
  1917.   L1p1 = list1;
  1918.   L1p2 = list1;
  1919.  
  1920.   while (S <= smax)
  1921.     {
  1922.       calcnews (ShellyArgs, O, S, &newS);
  1923.       S = newS;
  1924.  
  1925.       calcpoint (O, S, ShellyArgs, &L1p1);
  1926.       L1p2->next = L1p1;
  1927.       L1p2 = L1p1;
  1928.  
  1929.  
  1930.     }                /* while */
  1931.  
  1932.   *list = list1;
  1933.  
  1934.   return (0);
  1935.  
  1936. }                /* calcnodline */
  1937.  
  1938.  
  1939. /**********************************************/
  1940. /* CalcLine:                                  */
  1941. /*                                            */
  1942. /**********************************************/
  1943. int
  1944. calcline (double O, struct ShellyArguments *ShellyArgs, struct punkt **list)
  1945. {
  1946.   struct punkt *list1 = NULL, *L1p1, *L1p2;
  1947.   double x, y, z, R, S, Re, k;
  1948.   static double my;
  1949.   static double smin, smax, sd, a, b, A, beta, phi, omega, alpha, Scale;
  1950.   static int called = 0;
  1951.  
  1952.   if (called == 0)
  1953.     {
  1954.       smin = (*ShellyArgs).smin * pi / 180;
  1955.       smax = (*ShellyArgs).smax * pi / 180;
  1956.       sd = (*ShellyArgs).sd * pi / 180;
  1957.  
  1958.       alpha = (*ShellyArgs).alpha * pi / 180;
  1959.       beta = (*ShellyArgs).beta * pi / 180;
  1960.       phi = (*ShellyArgs).phi * pi / 180;
  1961.       omega = (*ShellyArgs).omega * pi / 180;
  1962.       my = (*ShellyArgs).my * pi / 180;
  1963.  
  1964.       a = (*ShellyArgs).a;
  1965.       b = (*ShellyArgs).b;
  1966.       A = (*ShellyArgs).A;
  1967.  
  1968.       Scale = (*ShellyArgs).Scale;
  1969.       called = 1;
  1970.     }
  1971.   counth = 0;
  1972.  
  1973.   for (S = smin; (S + sd) < smax; S = S + sd)
  1974.     {
  1975.       counth++;
  1976.       countp++;
  1977.  
  1978.       Re = pow ((pow (a, -2.0) * (cos (S) * cos (S)) + pow (b, -2.0) * (sin (S) * sin (S))), -0.5);
  1979.  
  1980.       k = calck (ShellyArgs, S, O);
  1981.  
  1982.       R = Re + k;
  1983.  
  1984.       /* alternatively: */
  1985.       /* R = pow((pow(a,2.0)*pow(cos(S),2.0)+pow(b,2.0)*pow(sin(S),2.0)),0.5); */
  1986.  
  1987.       x = Scale * (A * sin (beta) * cos (O) + R * cos (S + phi) * cos (O + omega) - R * sin (my) * sin (S + phi) * sin (O)) * exp (O * cot (alpha));
  1988.       y = Scale * (-1 * A * sin (beta) * sin (O) - R * cos (S + phi) * sin (O + omega) - R * sin (my) * sin (S + phi) * cos (O)) * exp (O * cot (alpha));
  1989.       z = Scale * (-1 * A * cos (beta) + R * sin (S + phi) * cos (my)) * exp (O * cot (alpha));
  1990.       if (camposspecified == NO)
  1991.     calccamera (x, y, z);
  1992.  
  1993.       if ((L1p1 = calloc (1, sizeof (struct punkt))) == NULL)
  1994.     {
  1995.       fprintf (stdout, "Shelly: NOT ENOUGH MEMORY!!! ... exiting ... !\n");
  1996.       if (S != smin)
  1997.         myfree (list1);
  1998.       return (5);
  1999.     }            /* if */
  2000.       if (S == smin)
  2001.     list1 = L1p1;
  2002.       else
  2003.     (*L1p2).next = L1p1;
  2004.       L1p2 = L1p1;
  2005.  
  2006.       (*L1p1).x = x;
  2007.       (*L1p1).y = y;
  2008.       (*L1p1).z = z;
  2009.       (*L1p1).s = S;
  2010.  
  2011.     }                /* for */
  2012.  
  2013.   *list = list1;
  2014.  
  2015.   return (0);
  2016.  
  2017. }                /* calcline */
  2018.  
  2019.  
  2020. /**********************************************/
  2021. /* calcnewo:                                  */
  2022. /*             SSIA :)                        */
  2023. /**********************************************/
  2024. void
  2025. calcnewo (struct ShellyArguments *SA, double Oold, double *newO)
  2026. {
  2027.   double O = Oold, od;
  2028.   int mittenodul = NO;
  2029.   od = SA->od * pi / 180;
  2030.  
  2031.   O += SA->Scano;
  2032.  
  2033.   while ((fabs (innodule (SA, O - Oold, Oold)) < SA->heightdiffo) && (O - Oold < od) && (mittenodul == NO))
  2034.     {
  2035.       O += SA->Scano;
  2036.       if ((innodule (SA, SA->Scano, Oold) < 0) && (innodule (SA, SA->Scano, O) > 0))
  2037.     {
  2038.       mittenodul = YES;
  2039.     }
  2040.     }
  2041.  
  2042.   *newO = O;
  2043.  
  2044.   return;
  2045.  
  2046. }                /* calcnewo */
  2047.  
  2048.  
  2049. /**********************************************/
  2050. /* CalcNewNod:                                */
  2051. /*             SSIA :)                        */
  2052. /**********************************************/
  2053. void
  2054. CalcNewNod (struct ShellyArguments *ShellyArgs, char *fout)
  2055. {
  2056.   struct punkt *list1 = NULL, *list2;
  2057.  
  2058.   double O, newO, omin, omax;
  2059.   FILE *fptemp, *fp;
  2060.   char *hilf, temp[laenge];
  2061.  
  2062.   omin = (*ShellyArgs).omin * pi / 180;
  2063.   omax = (*ShellyArgs).omax * pi / 180;
  2064.   O = omin;
  2065.  
  2066.   mycopystr (fout, temp, '\0');
  2067.   hilf = strchr (temp, '\0');
  2068.   if (hilf != NULL)
  2069.     mycopystr (".tmp", hilf, '\0');
  2070.  
  2071.  
  2072.   if ((fptemp = fopen (temp, "w+")) == NULL)
  2073.     {
  2074.       fprintf (stdout, "Could not open outfile: %s!\n", temp);
  2075.       exit (5);
  2076.     }
  2077.  
  2078.   if ((fp = fopen (fout, "w")) == NULL)
  2079.     {
  2080.       fprintf (stdout, "Could not open outfile: %s!\n", fout);
  2081.       exit (5);
  2082.     }
  2083.   if ((*ShellyArgs).output == X3D)
  2084.     writex3dheader (fp);
  2085.   if ((*ShellyArgs).output == T3D)
  2086.     writet3dheader (fp);
  2087.  
  2088.  
  2089.   fprintf (stdout, "Calculating the Shell:");
  2090.  
  2091.   if (calcnodline (omin, ShellyArgs, &list1) != 0)
  2092.     exit (5);
  2093.  
  2094.   while (O <= omax)
  2095.     {
  2096.       calcnewo (ShellyArgs, O, &newO);
  2097.       O = newO;
  2098.  
  2099.       if (calcnodline (O, ShellyArgs, &list2) != 0)
  2100.     exit (5);
  2101.  
  2102.       fprintf (stdout, ".");
  2103.       fflush (stdout);
  2104.  
  2105.       if ((*ShellyArgs).output == RPL)
  2106.     writerplline (fptemp, list1, list2, 1);
  2107.       if ((*ShellyArgs).output == POV)
  2108.     writepovtriangles (fptemp, list1, list2, 1);
  2109.       if ((*ShellyArgs).output == X3D)
  2110.     writex3dline (fptemp, list1, list2, 1);
  2111.       if ((*ShellyArgs).output == T3D)
  2112.     writet3dline (fptemp, list1, list2, 1);
  2113.  
  2114.       if ((*ShellyArgs).output == RAW)
  2115.     writerawtriangles (fp, list1, list2, 1);
  2116.  
  2117.       myfree (list1);
  2118.       list1 = list2;
  2119.  
  2120.     }
  2121.  
  2122.  
  2123.   if ((*ShellyArgs).output == POV)
  2124.     writepovheader (fp);
  2125.  
  2126.  
  2127.   if ((*ShellyArgs).output == RPL)
  2128.     writerplfinish (fptemp, fp, 1);
  2129.   if ((*ShellyArgs).output == POV)
  2130.     writepovfinish (fptemp, fp);
  2131.   if ((*ShellyArgs).output == X3D)
  2132.     writex3dfinish (fptemp, fp, 1);
  2133.   if ((*ShellyArgs).output == T3D)
  2134.     writet3dfinish (fptemp, fp, 1);
  2135.  
  2136.   fprintf (stdout, "\n");
  2137.  
  2138.   myfree (list1);
  2139.   if ((*ShellyArgs).output == X3D)
  2140.     writex3dline (fptemp, NULL, NULL, 2);    /* free temporary pointlist in writex3dline */
  2141.   if ((*ShellyArgs).output == T3D)
  2142.     writet3dline (fptemp, NULL, NULL, 2);    /* free temporary pointlist in writet3dline */
  2143.  
  2144.   if (fclose (fptemp) != 0)
  2145.     fprintf (stdout, "Error while closing file: %s!\n", temp);
  2146.  
  2147.   if (fclose (fp) != 0)
  2148.     fprintf (stdout, "Error while closing file: %s!\n", fout);
  2149.   remove (temp);
  2150. }                /* CalcNewNod */
  2151.  
  2152.  
  2153. /**********************************************/
  2154. /* CalcNodule:                                */
  2155. /*             SSIA :)                        */
  2156. /**********************************************/
  2157. void
  2158. CalcNodule (struct ShellyArguments *ShellyArgs, char *fout)
  2159. {
  2160.   struct punkt *list1 = NULL, *list2;
  2161.  
  2162.   double O, newO, omin, omax;
  2163.   FILE *fptemp, *fp;
  2164.   char *hilf, temp[laenge];
  2165.  
  2166.   omin = (*ShellyArgs).omin * pi / 180;
  2167.   omax = (*ShellyArgs).omax * pi / 180;
  2168.  
  2169.   O = omin;
  2170.  
  2171.   mycopystr (fout, temp, '\0');
  2172.   hilf = strchr (temp, '\0');
  2173.   if (hilf != NULL)
  2174.     mycopystr (".tmp", hilf, '\0');
  2175.  
  2176.  
  2177.   if ((fptemp = fopen (temp, "w+")) == NULL)
  2178.     {
  2179.       fprintf (stdout, "Could not open outfile: %s!\n", temp);
  2180.       exit (5);
  2181.     }
  2182.  
  2183.   if ((fp = fopen (fout, "w")) == NULL)
  2184.     {
  2185.       fprintf (stdout, "Could not open outfile: %s!\n", fout);
  2186.       exit (5);
  2187.     }
  2188.  
  2189.  
  2190.   fprintf (stdout, "Calculating the Shell:");
  2191.  
  2192.   if (calcline (omin, ShellyArgs, &list1) != 0)
  2193.     exit (5);
  2194.  
  2195.   if ((*ShellyArgs).output == RPL)
  2196.     writerplline (fptemp, list1, NULL, 0);
  2197.   if ((*ShellyArgs).output == T3D)
  2198.     writet3dline (fptemp, list1, NULL, 0);
  2199.   if ((*ShellyArgs).output == X3D)
  2200.     writex3dline (fptemp, list1, NULL, 0);
  2201.  
  2202.  
  2203.   while (O <= omax)
  2204.     {
  2205.  
  2206.       calcnewo (ShellyArgs, O, &newO);
  2207.       O = newO;
  2208.  
  2209.       if (calcline (O, ShellyArgs, &list2) != 0)
  2210.     exit (5);
  2211.  
  2212.       fprintf (stdout, ".");
  2213.       fflush (stdout);
  2214.  
  2215.       if ((*ShellyArgs).output == RPL)
  2216.     writerplline (fptemp, list1, NULL, 0);
  2217.       if ((*ShellyArgs).output == POV)
  2218.     writepovtriangles (fptemp, list1, list2, 0);
  2219.       if ((*ShellyArgs).output == T3D)
  2220.     writet3dline (fptemp, list1, NULL, 0);
  2221.       if ((*ShellyArgs).output == X3D)
  2222.     writex3dline (fptemp, list1, NULL, 0);
  2223.       if ((*ShellyArgs).output == RAW)
  2224.     writerawtriangles (fp, list1, list2, 0);
  2225.  
  2226.       myfree (list1);
  2227.       list1 = list2;
  2228.     }
  2229.  
  2230.   if ((*ShellyArgs).output == POV)
  2231.     writepovheader (fp);
  2232.   if ((*ShellyArgs).output == T3D)
  2233.     writet3dheader (fp);
  2234.   if ((*ShellyArgs).output == X3D)
  2235.     writex3dheader (fp);
  2236.  
  2237.  
  2238.   if ((*ShellyArgs).output == RPL)
  2239.     writerplfinish (fptemp, fp, 0);
  2240.   if ((*ShellyArgs).output == T3D)
  2241.     writet3dfinish (fptemp, fp, 0);
  2242.   if ((*ShellyArgs).output == POV)
  2243.     writepovfinish (fptemp, fp);
  2244.   if ((*ShellyArgs).output == X3D)
  2245.     writex3dfinish (fptemp, fp, 0);
  2246.  
  2247.   fprintf (stdout, "\n");
  2248.  
  2249.   myfree (list1);
  2250.  
  2251.  
  2252.   if (fclose (fptemp) != 0)
  2253.     fprintf (stdout, "Error while closing file: %s!\n", temp);
  2254.  
  2255.   if (fclose (fp) != 0)
  2256.     fprintf (stdout, "Error while closing file: %s!\n", fout);
  2257.   remove (temp);
  2258. }                /* CalcNodule */
  2259.  
  2260.  
  2261. /**********************************************/
  2262. /* CalcShell:                                 */
  2263. /*             SSIA :)                        */
  2264. /**********************************************/
  2265. void
  2266. CalcShell (struct ShellyArguments *ShellyArgs, char *fout)
  2267. {
  2268.   struct punkt *list1 = NULL, *list2;
  2269.  
  2270.   double O, omin, omax, od;
  2271.   FILE *fptemp, *fp;
  2272.   char temp[laenge], *hilf;
  2273.  
  2274.   omin = (*ShellyArgs).omin * pi / 180;
  2275.   omax = (*ShellyArgs).omax * pi / 180;
  2276.   od = (*ShellyArgs).od * pi / 180;
  2277.  
  2278.  
  2279.   mycopystr (fout, temp, '\0');
  2280.   hilf = strchr (temp, '\0');
  2281.   if (hilf != NULL)
  2282.     mycopystr (".tmp", hilf, '\0');
  2283.  
  2284.   if ((fptemp = fopen (temp, "w+")) == NULL)
  2285.     {
  2286.       fprintf (stdout, "Could not open outfile: %s!\n", temp);
  2287.       exit (5);
  2288.     }
  2289.  
  2290.   if ((fp = fopen (fout, "w")) == NULL)
  2291.     {
  2292.       fprintf (stdout, "Could not open outfile: %s!\n", fout);
  2293.       exit (5);
  2294.     }
  2295.  
  2296.  
  2297.  
  2298.  
  2299.   fprintf (stdout, "Calculating the Shell:");
  2300.  
  2301.   if (calcline (omin, ShellyArgs, &list1) != 0)
  2302.     exit (5);
  2303.  
  2304.  
  2305.   if ((*ShellyArgs).output == RPL)
  2306.     writerplline (fptemp, list1, NULL, 0);
  2307.   if ((*ShellyArgs).output == T3D)
  2308.     writet3dline (fptemp, list1, NULL, 0);
  2309.   if ((*ShellyArgs).output == X3D)
  2310.     writex3dline (fptemp, list1, NULL, 0);
  2311.  
  2312.   for (O = omin + od; (O + od) < omax; O = O + od)
  2313.     {
  2314.  
  2315.       counth = 0;
  2316.  
  2317.       if (calcline (O, ShellyArgs, &list2) != 0)
  2318.     exit (5);
  2319.  
  2320.       fprintf (stdout, ".");
  2321.       fflush (stdout);
  2322.  
  2323.  
  2324.       if ((*ShellyArgs).output == RPL)
  2325.     writerplline (fptemp, list1, NULL, 0);
  2326.       if ((*ShellyArgs).output == POV)
  2327.     writepovtriangles (fptemp, list1, list2, 0);
  2328.       if ((*ShellyArgs).output == T3D)
  2329.     writet3dline (fptemp, list1, NULL, 0);
  2330.       if ((*ShellyArgs).output == RAW)
  2331.     writerawtriangles (fp, list1, list2, 0);
  2332.       if ((*ShellyArgs).output == X3D)
  2333.     writex3dline (fptemp, list1, NULL, 0);
  2334.  
  2335.  
  2336.       myfree (list1);
  2337.       list1 = list2;
  2338.  
  2339.     }                /* for */
  2340.  
  2341.   if ((*ShellyArgs).output == POV)
  2342.     writepovheader (fp);
  2343.   if ((*ShellyArgs).output == T3D)
  2344.     writet3dheader (fp);
  2345.   if ((*ShellyArgs).output == X3D)
  2346.     writex3dheader (fp);
  2347.  
  2348.  
  2349.   if ((*ShellyArgs).output == RPL)
  2350.     writerplfinish (fptemp, fp, 0);
  2351.   if ((*ShellyArgs).output == T3D)
  2352.     writet3dfinish (fptemp, fp, 0);
  2353.   if ((*ShellyArgs).output == POV)
  2354.     writepovfinish (fptemp, fp);
  2355.   if ((*ShellyArgs).output == X3D)
  2356.     writex3dfinish (fptemp, fp, 0);
  2357.  
  2358.   fprintf (stdout, "\n");
  2359.  
  2360.   myfree (list1);
  2361.  
  2362.  
  2363.   if (fclose (fptemp) != 0)
  2364.     fprintf (stdout, "Error while closing file: %s!\n", temp);
  2365.  
  2366.   if (fclose (fp) != 0)
  2367.     fprintf (stdout, "Error while closing file: %s!\n", fout);
  2368.   remove (temp);
  2369. }                /* CalcShell */
  2370.  
  2371.  
  2372. /**********************************************/
  2373. /* RenderPov:                                 */
  2374. /*           invoke pov for rendering         */
  2375. /**********************************************/
  2376. void
  2377. RenderPov (struct ShellyArguments *ShellyArgs, char *fout)
  2378. {
  2379.   char call[laenge];
  2380.  
  2381.   printf ("Rendering...\n");
  2382.  
  2383.   mycopystr ("pov ", call, '\0');
  2384.   mycopystr ((*ShellyArgs).povargs, &call[4], '\0');
  2385.   strcat (call, " +i");
  2386.   strcat (call, fout);
  2387.   system (call);
  2388.  
  2389.  
  2390. }                /* RenderPov */
  2391.  
  2392.  
  2393. /********************************************/
  2394. /*main:                                     */
  2395. /********************************************/
  2396. int
  2397. main (int ac, char **av)
  2398. {
  2399.   struct ShellyArguments *ShellyArgs;
  2400.  
  2401.   fprintf (stdout, "ShellyV1.5, the ShellShapeGenerator by RANDi\n");
  2402.  
  2403.   if (ac != 3)
  2404.     {
  2405.       fprintf (stdout, "USAGE:\n\n");
  2406.       fprintf (stdout, "   'shelly infilename outfilename'\n\n");
  2407.       exit (1);
  2408.     }                /* if */
  2409.  
  2410.  
  2411.   if ((ShellyArgs = calloc (1, sizeof (struct ShellyArguments))) != NULL);
  2412.   {
  2413.     ReadInfile (ShellyArgs, av[1]);
  2414.  
  2415.     if (ShellyArgs->mode == NORMAL)
  2416.       CalcShell (ShellyArgs, av[2]);
  2417.     if (ShellyArgs->mode == NODULE)
  2418.       CalcNodule (ShellyArgs, av[2]);
  2419.     if (ShellyArgs->mode == NEWNOD)
  2420.       CalcNewNod (ShellyArgs, av[2]);
  2421.  
  2422.     if (ShellyArgs->Render == YES)
  2423.       if (ShellyArgs->output != POV)
  2424.     fprintf (stdout, "Rendering is only available for POV-output!\n(Ever tried to feed a RPL-Macro into POV? ;))\n");
  2425.       else
  2426.     RenderPov (ShellyArgs, av[2]);
  2427.   }
  2428.   exit (0);
  2429. }
  2430.